using FytSoa.Application.Hr.Param;
using FytSoa.Common.Extensions;
using FytSoa.Domain.Hr;
using FytSoa.Sugar;
using FytSoa.Common.Utils;
using FytSoa.Common.Param;
using FytSoa.Common.Result;
using FytSoa.Domain.Sys;
using Mapster;
using Masuit.Tools.Security;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;

namespace FytSoa.Application.Hr;

/// <summary>
/// HR-员工服务接口
/// </summary>
[ApiExplorerSettings(GroupName = "v8")]
public class HrEmployeeService : IApplicationService 
{
    private readonly SugarRepository<HrEmployee> _thisRepository;
    private readonly SugarRepository<SysCode> _codeRepository;
    private readonly SugarRepository<SysAdmin> _adminRepository;
    public HrEmployeeService(SugarRepository<HrEmployee> thisRepository
    ,SugarRepository<SysCode> codeRepository
    ,SugarRepository<SysAdmin> adminRepository)
    {
        _thisRepository = thisRepository;
        _codeRepository = codeRepository;
        _adminRepository = adminRepository;
    }
    
    /// <summary>
    /// 查询所有——分页
    /// </summary>
    /// <param name="param"></param>
    /// <returns></returns>
    public async Task<PageResult<HrEmployeeDto>> GetPagesAsync(HrEmployeeSearchParam param)
    {
        var queryQuery = _thisRepository.AsQueryable()
            .WhereIF(param.OrgId!=0,m=> SqlFunc.Subqueryable<HrOrganization>()
                .Where(o=> m.OrganizationId==o.Id && SqlFunc.ToString(o.ParentIdList).Contains(param.OrgId.ToString())).Any())
            .WhereIF(!string.IsNullOrEmpty(param.IdArray),m=>param.IdArray.StrToListLong().Contains(m.Id))
            .WhereIF(!string.IsNullOrEmpty(param.Key),
                m => m.Name.Contains(param.Key) || m.WorkNumber.Contains(param.Key) || m.Phone.Contains(param.Key));
            
        if (!string.IsNullOrEmpty(param.Query))
        {
            var jsonParam=_thisRepository.Context.Utilities.JsonToConditionalModels(param.Query);
            queryQuery.Where(jsonParam);
        }
        var query = await queryQuery
            .Includes(m=>m.OrganizationObj)
            .Includes(m=>m.JobSourceObj)
            .Includes(m=>m.StatusObj)
            .Includes(m=>m.PostObj)
            .OrderByDescending(m=>m.Id)
            .ToPageAsync(param.Page, param.Limit);
        return query.Adapt<PageResult<HrEmployeeDto>>();
    }

    /// <summary>
    /// 查询员工状态的数量
    /// </summary>
    /// <returns></returns>
    public async Task<List<HrEmployeeStatusDto>> GetStatusTotal()
    {
        var codeList = await _codeRepository.GetListAsync(m => m.TypeId == 1595691980208345088 && m.Status);
        var res = await _thisRepository.AsQueryable()
            .GroupBy(m => m.Status)
            .Select(m => new HrEmployeeStatusDto()
            {
                Id = m.Status,
                Count = SqlFunc.AggregateCount(m.Id)
            })
            .ToListAsync();
        foreach (var item in codeList)  
        {
            if (res.All(m => m.Id != item.Id))
            {
                res.Add(new HrEmployeeStatusDto()
                {
                    Id=item.Id,
                    Name = item.Name
                });
            }
            else
            {
                res.FirstOrDefault(m => m.Id == item.Id)!.Name = item.Name;
            }
        }
        return res;
    }

    /// <summary>
    /// 根据主键查询
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [HttpGet("{id}")]
    public async Task<HrEmployeeDto> GetAsync(long id)
    {
        var model = await _thisRepository.AsQueryable()
            .Includes(m=>m.LeaderObj)
            .Includes(m=>m.OrganizationObj)
            .FirstAsync(m=>m.Id==id);
        return model.Adapt<HrEmployeeDto>();
    }

    /// <summary>
    /// 添加
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    public async Task<bool> AddAsync(HrEmployeeAdd model)
    {
        model.Letter = model.Name.ConvertToPinYinFirst();
        return await _thisRepository.InsertAsync(model.Adapt<HrEmployee>());
    }

    /// <summary>
    /// 修改
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    public async Task<bool> ModifyAsync(HrEmployeeAdd model)
    {
        model.Letter = model.Name.ConvertToPinYinFirst();
        return await _thisRepository.UpdateAsync(model.Adapt<HrEmployee>());
    }
    
    /// <summary>
    /// 设置管理员
    /// </summary>
    /// <param name="ids"></param>
    /// <returns></returns>
    [UnitOfWork]
    public async Task ModifySetAdminAsync([FromBody]List<long> ids)
    {
        await _thisRepository.UpdateAsync(m => new HrEmployee()
        {
            IsAdmin = true
        },m=>ids.Contains(m.Id));

        var list = await _thisRepository.GetListAsync(m => ids.Contains(m.Id));

        var addList = new List<SysAdmin>();
        foreach (var item in list)
        {
            addList.Add(new SysAdmin()
            {
                EmployeeId=item.Id,
                PostGroup=new List<string>(){item.PostId.ToString()},
                OrganizeId=item.OrganizationId,
                //LoginAccount=(item.Name.ConvertToPinYin()+"_"+StringUtils.RandomString(5)).ToLower(),
                LoginAccount = item.WorkNumber,
                LoginPassWord="123456!".MDString().ToLower().AESEncrypt(),
                Avatar=item.Avatar,
                FullName=item.Name,
                Mobile=item.Phone,
                Email=item.Email,
                Sex = item.Sex
            });
        }

        var isAny = await _adminRepository.IsAnyAsync(m =>
            addList.Select(a => a.LoginAccount).Contains(m.LoginAccount));
        if (isAny)
        {
            throw new BusinessException("存在相同的账号编号，请核对！~");
        }
        await _adminRepository.InsertRangeAsync(addList);
    }
    
    /// <summary>
    /// 取消管理员
    /// </summary>
    /// <param name="ids"></param>
    /// <returns></returns>
    [UnitOfWork]
    public async Task ModifyCancelAdminAsync([FromBody]List<long> ids)
    {
        await _thisRepository.UpdateAsync(m => new HrEmployee()
        {
            IsAdmin = false
        },m=>ids.Contains(m.Id));
        
        // 删除取消的管理员
        await _adminRepository.DeleteAsync(m => ids.Contains(m.EmployeeId));

        // 删除用户和角色关系
        var adminRoleRepository = _thisRepository.ChangeRepository<SugarRepository<SysAdminRole>>();
        await adminRoleRepository.DeleteAsync(m =>
            SqlFunc.Subqueryable<SysAdmin>().Where(a => a.Id == m.AdminId && ids.Contains(a.EmployeeId)).Any());
    }

    /// <summary>
    /// 删除,支持批量
    /// </summary>
    /// <param name="ids"></param>
    /// <returns></returns>
    [HttpDelete]
    public async Task<bool> DeleteAsync([FromBody]List<long> ids) =>
        await _thisRepository.DeleteAsync(m=>ids.Contains(m.Id));
}
